package com.martian.service.impl;

import com.martian.common.constant.TokenInfo;
import com.martian.common.enums.UserErrorCodeEnum;
import com.martian.common.exception.UserException;
import com.martian.common.util.Md5Util;
import com.martian.common.util.ThreadLocalMap;
import com.martian.common.util.TokenUtil;
import com.martian.mapper.ManagerMapper;
import com.martian.mapper.MovieMapper;
import com.martian.mapper.UserMapper;
import com.martian.pojo.dto.AllUsers;
import com.martian.pojo.dto.LoginSuccessDto;
import com.martian.pojo.dto.RecMovieDto;
import com.martian.pojo.dto.UserLoginDto;
import com.martian.pojo.entity.Manager;
import com.martian.pojo.entity.User;
import com.martian.pojo.form.ManagerLoginForm;
import com.martian.pojo.form.UserRegisterForm;
import com.martian.service.ManagerService;
import com.martian.service.redis.RedisRepository;
import io.swagger.models.auth.In;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author martian
 * @version V1.0.0
 * @Description
 * @date 2023-04-16 15:06
 */
@Service
public class ManagerServiceImpl implements ManagerService {
    @Resource
    ManagerMapper managerMapper;
    @Resource
    UserMapper userMapper;
    @Resource
    MovieMapper movieMapper;
    @Resource
    private RedisRepository redisRepository;

    @Resource
    private UserServiceImpl userService;
    @Override
    public LoginSuccessDto managerLogin(ManagerLoginForm managerLoginForm) {
        Manager manager = managerMapper.selectManagerByName(managerLoginForm.getManagerName());
        String managerPwd = Md5Util.MD5Encode(managerLoginForm.getManagerPassword()+manager.getManagerSalt());
        if (manager == null){
            throw new UserException("用户名不存在");
        }else if(!manager.getManagerPassword().equals(managerPwd)){
            throw new UserException("密码错误");
        } else {
//            判断是否异地登录，对应如下场景；在用户已经登录系统的情况下；用户换了一个浏览器或者在另外一台主机登录
            String oldToken = redisRepository.selectManagerLoginToken(manager.getManagerId());
            if (null != oldToken) {
                //如果存在异地登录，删除原有的token，刷新token
                redisRepository.deleteManagerLoginToken(oldToken);
                redisRepository.deleteManagerLoginId(manager.getManagerId());
            }
            //得到一个accessToken，生成tokenInfo
            TokenInfo tokenInfo = new TokenInfo();
            tokenInfo.setAccessToken(TokenUtil.genToken());
            tokenInfo.setUserId(manager.getManagerId());
            LoginSuccessDto messageSuccessLoginDto = new LoginSuccessDto(tokenInfo, manager.getManagerName());
            //保存这个用户和token信息
            redisRepository.saveManagerLoginToken(tokenInfo);
            redisRepository.saveManagerLoginId(tokenInfo);
            return messageSuccessLoginDto;
        }
    }
    @Override
    public boolean userRegister(UserRegisterForm userRegisterForm) {
        if(!userRegisterForm.getUserPwd().equals(userRegisterForm.getUserConfirmPwd())){
            throw new UserException(UserErrorCodeEnum.USER_PWD_CONFIRM_ERROR);
        }
        UserLoginDto user = userMapper.selectByName(userRegisterForm.getUserName());
        if(user != null){
            throw new UserException(UserErrorCodeEnum.USER_NAME_NOT_UNIQUE);
        }
        String user_salt = Md5Util.salt();
        String user_md5_pwd = Md5Util.MD5Encode(userRegisterForm.getUserPwd()+user_salt);
        userMapper.insertNewUser(userRegisterForm.getUserName(),user_md5_pwd,user_salt,1);
        return true;
    }

    @Override
    public Double coverageMetric() {
        StopWatch sw = new StopWatch("test");
        sw.start("task1");
        Set<Integer> AllRecMovieIds = new HashSet<>();
        for (AllUsers selectAllUser : userMapper.selectAllUsers()) {
            List<Integer> recMovieIds =  userService.recMovieIds(selectAllUser.getUserId(),10);
            AllRecMovieIds.addAll(recMovieIds);
        }
        sw.stop();
        System.out.println(sw.prettyPrint());
        return Double.valueOf(AllRecMovieIds.size())/movieMapper.selectAllMovieNum();
    }
}
